home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 11 / CU Amiga Magazine's Super CD-ROM 11 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-06].iso / cucd / programming / oberonv4 / source / system / menuviewers.mod (.txt) < prev    next >
Oberon Text  |  1990-01-01  |  8KB  |  212 lines

  1. Syntax10.Scn.Fnt
  2. MODULE MenuViewers; (*JG 26.8.90 / 16.9.93*)
  3.     IMPORT Input, Display, Viewers, Oberon;
  4.     CONST extend* = 0; reduce* = 1; FrameColor = 15;
  5.     TYPE
  6.     Viewer* = POINTER TO ViewerDesc;
  7.     ViewerDesc* = RECORD
  8.         (Viewers.ViewerDesc)
  9.         menuH*: INTEGER
  10.     END;
  11.     ModifyMsg* = RECORD
  12.         (Display.FrameMsg)
  13.         id*: INTEGER;
  14.         dY*, Y*, H*: INTEGER
  15.     END;
  16.     VAR Ancestor*: Viewer;
  17.     PROCEDURE Copy (V: Viewer; VAR V1: Viewer);
  18.         VAR Menu, Main: Display.Frame; M: Oberon.CopyMsg;
  19.     BEGIN
  20.         Menu := V.dsc; Main := V.dsc.next;
  21.         NEW(V1); V1^ := V^; V1.state := 0;
  22.         M.F := NIL; Menu.handle(Menu, M); V1.dsc := M.F;
  23.         M.F := NIL; Main.handle(Main, M); V1.dsc.next := M.F
  24.     END Copy;
  25.     PROCEDURE Draw (V: Viewers.Viewer);
  26.     BEGIN
  27.         Display.ReplConst(FrameColor, V.X, V.Y, 1, V.H, 0);
  28.         Display.ReplConst(FrameColor, V.X + V.W - 1, V.Y, 1, V.H, 0);
  29.         Display.ReplConst(FrameColor, V.X + 1, V.Y, V.W - 2, 1, 0);
  30.         Display.ReplConst(FrameColor, V.X + 1, V.Y + V.H - 1, V.W - 2, 1, 0)
  31.     END Draw;
  32.     PROCEDURE Extend (V: Viewer; newY: INTEGER);
  33.         VAR dH: INTEGER;
  34.     BEGIN dH := V.Y - newY;
  35.         IF dH > 0 THEN
  36.         Display.ReplConst(Display.black, V.X + 1, newY + 1, V.W - 2, dH, 0);
  37.         Display.ReplConst(FrameColor, V.X, newY, 1, dH, 0);
  38.         Display.ReplConst(FrameColor, V.X + V.W - 1, newY, 1, dH, 0);
  39.         Display.ReplConst(FrameColor, V.X + 1, newY, V.W - 2, 1, 0)
  40.         END
  41.     END Extend;
  42.     PROCEDURE Reduce (V: Viewer; newY: INTEGER);
  43.     BEGIN Display.ReplConst(FrameColor, V.X + 1, newY, V.W - 2, 1, 0)
  44.     END Reduce;
  45.     PROCEDURE Grow (V: Viewer; oldH: INTEGER);
  46.         VAR dH: INTEGER;
  47.     BEGIN dH := V.H - oldH;
  48.         IF dH > 0 THEN
  49.             Display.ReplConst(FrameColor, V.X, V.Y + oldH, 1, dH, 0);
  50.             Display.ReplConst(FrameColor, V.X + V.W - 1, V.Y + oldH, 1, dH, 0);
  51.             Display.ReplConst(FrameColor, V.X + 1, V.Y + V.H - 1, V.W - 2, 1, 0)
  52.         END
  53.     END Grow;
  54.     PROCEDURE Shrink (V: Viewer; newH: INTEGER);
  55.     BEGIN Display.ReplConst(FrameColor, V.X + 1, V.Y + newH - 1, V.W - 2, 1, 0)
  56.     END Shrink;
  57.     PROCEDURE Adjust (F: Display.Frame; id, dY, Y, H: INTEGER);
  58.         VAR M: ModifyMsg;
  59.     BEGIN M.id := id; M.dY := dY; M.Y := Y; M.H := H; F.handle(F, M); F.Y := Y; F.H := H
  60.     END Adjust;
  61.     PROCEDURE Restore (V: Viewer);
  62.         VAR Menu, Main: Display.Frame;
  63.     BEGIN
  64.         Menu := V.dsc; Main := V.dsc.next;
  65.         Oberon.RemoveMarks(V.X, V.Y, V.W, V.H);
  66.         Draw(V);
  67.         Menu.X := V.X + 1; Menu.Y := V.Y + V.H - 1; Menu.W := V.W - 2; Menu.H := 0;
  68.         Main.X := V.X + 1; Main.Y := V.Y + V.H - V.menuH; Main.W := V.W - 2; Main.H := 0;
  69.         IF V.H > V.menuH + 1 THEN
  70.             Adjust(Menu, extend, 0, V.Y + V.H - V.menuH, V.menuH - 1);
  71.             Adjust( Main, extend, 0, V.Y + 1, V.H - V.menuH - 1)
  72.         ELSE Adjust(Menu, extend, 0, V.Y + 1, V.H - 2)
  73.         END
  74.     END Restore;
  75.     PROCEDURE Modify (V: Viewer; Y, H: INTEGER);
  76.         VAR Menu, Main: Display.Frame;
  77.     BEGIN
  78.         Menu := V.dsc; Main := V.dsc.next;
  79.         IF Y < V.Y THEN (*extend*)
  80.             Oberon.RemoveMarks(V.X, Y, V.W, V.Y - Y);
  81.             Extend(V, Y);
  82.             IF H > V.menuH + 1 THEN
  83.                 Adjust(Menu, extend, 0, Y + H - V.menuH, V.menuH - 1);
  84.                 Adjust(Main, extend, 0, Y + 1, H - V.menuH - 1)
  85.             ELSE Adjust(Menu, extend, 0, Y + 1, H - 2)
  86.             END
  87.         ELSIF Y > V.Y THEN (*reduce*)
  88.             Oberon.RemoveMarks(V.X, V.Y, V.W, V.H);
  89.             IF H > V.menuH + 1 THEN
  90.                  Adjust(Main, reduce, 0, Y + 1, H - V.menuH - 1);
  91.                  Adjust(Menu, reduce, 0, Y + H - V.menuH, V.menuH - 1)
  92.             ELSE
  93.                  Adjust(Main, reduce, 0, Y + H - V.menuH, 0);
  94.                  Adjust(Menu, reduce, 0, Y + 1, H - 2)
  95.             END;
  96.             Reduce(V, Y)
  97.         END
  98.     END Modify;
  99.     PROCEDURE Change (V: Viewer; X, Y: INTEGER; Keys: SET);
  100.         VAR Menu, Main: Display.Frame;
  101.             V1: Viewers.Viewer; keysum: SET; Y0, dY, H: INTEGER;
  102.     BEGIN (*Keys # {}*)
  103.         Menu := V.dsc; Main := V.dsc.next;
  104.         Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, X, Y);
  105.         Display.ReplConst(Display.white, V.X + 1, V.Y + V.H (* - 1*) - V.dsc.H, V.W - 2, V.dsc.H - 1, 2);    (* << *)
  106.         Y0 := Y; 
  107.         keysum := Keys;
  108.         LOOP
  109.             Input.Mouse(Keys, X, Y);
  110.             IF Keys = {} THEN EXIT END;
  111.             keysum := keysum + Keys;
  112.             Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, X, Y)
  113.         END;
  114.         Display.ReplConst(Display.white, V.X + 1, V.Y + V.H (* - 1*) - V.dsc.H, V.W - 2, V.dsc.H - 1, 2);    (* << *)
  115.         IF ~(0 IN keysum) THEN
  116.             IF 1 IN keysum THEN V1 := Viewers.This(X, Y);
  117.                 IF (V1 IS Viewer) & (Y > V1.Y + V1.H - V1(Viewer).menuH - 2) THEN Y := V1.Y + V1.H END;
  118.                 IF Y < V1.Y + V.menuH + 2 THEN Y := V1.Y + V.menuH + 2 END;
  119.                 Viewers.Close(V); Viewers.Open(V, X, Y); Restore(V)
  120.             ELSE
  121.                 IF Y > Y0 THEN (*extend*) dY := Y - Y0;
  122.                     V1 := Viewers.Next(V);
  123.                     IF V1.state > 1 THEN
  124.                         IF V1 IS Viewer THEN
  125.                             IF V1.H < V1(Viewer).menuH + 2 THEN dY := 0
  126.                                 ELSIF V1.H < V1(Viewer).menuH + 2 + dY THEN dY := V1.H - V1(Viewer).menuH - 2
  127.                             END
  128.                         ELSIF V1.H < 1 + dY THEN dY := V1.H - 1
  129.                         END
  130.                     ELSIF V1.H < dY THEN dY := V1.H
  131.                     END;
  132.                     Viewers.Change(V, V.Y + V.H + dY);
  133.                     Oberon.RemoveMarks(V.X, V.Y, V.W, V.H);
  134.                     Grow(V, V.H - dY);
  135.                     IF V.H > V.menuH + 1 THEN
  136.                         Adjust(Menu, extend, dY, V.Y + V.H - V.menuH, V.menuH - 1);
  137.                         Adjust(Main, extend, dY, V.Y + 1, V.H - V.menuH - 1)
  138.                     ELSE    (*V.H > 1*)
  139.                         Adjust(Menu, extend, dY, V.Y + 1, V.H - 2);
  140.                         Adjust(Main, extend, dY, V.Y + V.H - V.menuH, 0)
  141.                     END
  142.                 ELSIF Y < Y0 THEN (*reduce*) dY := Y0 - Y;
  143.                     IF V.H >= V.menuH + 2 THEN
  144.                         IF V.H < V.menuH + 2 + dY THEN dY := V.H - V.menuH - 2 END;
  145.                         Oberon.RemoveMarks(V.X, V.Y, V.W, V.H);
  146.                         H := V.H - dY;
  147.                         Adjust(Main, reduce, dY, V.Y + 1, H - V.menuH - 1);
  148.                         Adjust(Menu, reduce, dY, V.Y + H - V.menuH, V.menuH - 1);
  149.                         Shrink(V, H);
  150.                         Viewers.Change(V, V.Y + H)
  151.                     END
  152.                 END
  153.             END
  154.         END
  155.     END Change;
  156.     PROCEDURE Suspend (V: Viewer);
  157.         VAR Menu, Main: Display.Frame;
  158.     BEGIN
  159.         Menu := V.dsc; Main := V.dsc.next;
  160.         Adjust(Main, reduce, 0, V.Y + V.H - V.menuH, 0);
  161.         Adjust(Menu, reduce, 0, V.Y + V.H - 1, 0)
  162.     END Suspend;
  163.     PROCEDURE Handle* (V: Display.Frame; VAR M: Display.FrameMsg);
  164.         VAR Menu, Main: Display.Frame; V1: Viewer;
  165.     BEGIN
  166.         WITH V: Viewer DO Ancestor := V;
  167.             Menu := V.dsc; Main := V.dsc.next;
  168.             IF M IS Oberon.InputMsg THEN
  169.             WITH M: Oberon.InputMsg DO
  170.                 IF M.id = Oberon.track THEN
  171.                     IF M.Y < V.Y + 1 THEN Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, M.X, M.Y)
  172.                     ELSIF M.Y < V.Y + V.H - V.menuH THEN Main.handle(Main, M)
  173.                     ELSIF M.Y < V.Y + V.H - V.menuH + 2 THEN Menu.handle(Menu, M)
  174.                     ELSIF M.Y < V.Y + V.H - 1 THEN
  175.                         IF 2 IN M.keys THEN Change(V, M.X, M.Y, M.keys)
  176.                         ELSE Menu.handle(Menu, M)
  177.                         END
  178.                     ELSE Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, M.X, M.Y)
  179.                     END
  180.                 ELSE Menu.handle(Menu, M); Main.handle(Main, M)
  181.                 END
  182.             END
  183.             ELSIF M IS Oberon.ControlMsg THEN
  184.                 WITH M: Oberon.ControlMsg DO
  185.                     IF M.id = Oberon.mark THEN
  186.                         Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, M.X, M.Y);
  187.                         Oberon.DrawCursor(Oberon.Pointer, Oberon.Star, M.X, M.Y)
  188.                     ELSE Menu.handle(Menu, M); Main.handle(Main, M)
  189.                     END
  190.                 END
  191.             ELSIF M IS Oberon.CopyMsg THEN
  192.                 WITH M: Oberon.CopyMsg DO Copy(V(Viewer), V1); M.F := V1 END
  193.             ELSIF M IS Viewers.ViewerMsg THEN
  194.                 WITH M: Viewers.ViewerMsg DO
  195.                     IF M.id = Viewers.restore THEN Restore(V)
  196.                     ELSIF M.id = Viewers.modify THEN Modify(V, M.Y, M.H)
  197.                     ELSIF M.id = Viewers.suspend THEN Suspend(V)
  198.                     END
  199.                 END
  200.             ELSE Menu.handle(Menu, M); Main.handle(Main, M)
  201.             END
  202.         END
  203.     END Handle;
  204.     PROCEDURE New* (Menu, Main: Display.Frame; menuH, X, Y: INTEGER): Viewer; 
  205.         VAR V: Viewer;
  206.     BEGIN NEW(V);
  207.         V.handle := Handle; V.dsc := Menu; V.dsc.next := Main; V.menuH := menuH;
  208.         Viewers.Open(V, X, Y); Restore(V);
  209.         RETURN V
  210.     END New;
  211. END MenuViewers.
  212.